#include <header.h>


/**
 * 1. 使用多线程模拟卖票逻辑:
 * 一个线程卖票: 票未必每一次都能卖掉, 每一次买票的人在随机的状态下(假设:用产生一个随机数<0.5表示有人要买票)选择是否买票
 * 另一个线程加票
 * 在初始情况下有20张票的情况下:每次卖一张
 * 当第一次票小于5张的时候追加一次票: 10张票
 * 卖完为止
*/

static int  pool = 20;
pthread_mutex_t lock;
bool flag = true;

float prob(){
	int p = rand() % 100;
	return (float)p / 100;
}

int get(){
	pool--;
	printf("get a token, and remain %d\n", pool);
	if(pool == 0){
		return 1;
	}
	return 0;
}

void put(){
	printf("add to 10 token\n");
	pool = 10;
}


// 只要操作临界区都要加锁

void* consumer(void *arg){
	while(1){
		if(prob() > 0.50F){
			printf("no people\n");
			usleep(1000);
			continue;
		}

		// 加锁
    	pthread_mutex_lock(&lock);
		// 此处可能有bug，消费者可能一直占用cpu，所以要加判断
		// 第一次小于5张了不能再卖了
		if(pool <= 5 && flag){
			pthread_mutex_unlock(&lock);
			continue;
		}
		int ret = get();
		pthread_mutex_unlock(&lock);
		// 解锁
		if(ret){
			return NULL;
			// exit
		}
	}
}

void* producer(void *arg){
	while(1){
		// 加锁
		pthread_mutex_lock(&lock);
		if(pool <= 5){
			put();
			// return前要解锁
			flag = false;
			pthread_mutex_unlock(&lock);
			return NULL;
			// exit
		}
		pthread_mutex_unlock(&lock);
		// 解锁
	}
}

int main(void){
	// 随机数
	srand(time(NULL));

	pthread_mutex_init(&lock, NULL);
	
	pthread_t consumer_id;
	pthread_t producer_id;

	int retp1 = pthread_create(&consumer_id, NULL, consumer, NULL); 
	THREAD_ERROR_CHECK(retp1, "consumer thread create");

	int retp2 = pthread_create(&producer_id, NULL, producer, NULL);
	THREAD_ERROR_CHECK(retp2, "producer thread create");



	int retj2 = pthread_join(producer_id, NULL);
	THREAD_ERROR_CHECK(retj2, "join producer");
	int retj1 = pthread_join(consumer_id, NULL);
	THREAD_ERROR_CHECK(retj1, "join consumer");


	printf("pool = %d\n", pool);
	return 0;
}